package com.thwj.project.app.service;

import cn.hutool.core.util.PhoneUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.thwj.common.constant.HttpStatus;
import com.thwj.common.exception.ServiceException;
import com.thwj.common.utils.StringUtils;
import com.thwj.common.utils.WzDateUtil;
import com.thwj.framework.mybatis_plus.GeoUtil;
import com.thwj.framework.security.LoginUser;
import com.thwj.project.app.api.param.UserAuthenticationParam;
import com.thwj.project.app.api.param.UserInfoParam;
import com.thwj.project.app.api.vo.UserAttentionVo;
import com.thwj.project.app.api.vo.UserAuthenticationVo;
import com.thwj.project.app.api.vo.UserFollowVo;
import com.thwj.project.app.api.vo.UserInfoVo;
import com.thwj.project.app.event.UserMessageEvent;
import com.thwj.project.biz.domain.*;
import com.thwj.project.biz.enums.AuditStatusEnum;
import com.thwj.project.biz.enums.MessageTypeEnum;
import com.thwj.project.biz.enums.UserAuthenticationTypeEnum;
import com.thwj.project.biz.enums.UserStatusEnum;
import com.thwj.project.biz.service.*;
import com.thwj.project.push.MpPushMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Transactional
@Service
public class AppUserService {

    @Autowired
    IUserService userService;
    @Autowired
    IUserAuthenticationService userAuthenticationService;
    @Lazy
    @Autowired
    MpPushMessageService mpPushMessageService;
    @Autowired
    IUserDdService userDdService;
    @Autowired
    IUserAttentionService userAttentionService;
    @Autowired
    UserInfoResolver userInfoResolver;
    @Autowired
    UserVipResolver userVipResolver;
    @Autowired
    ApplicationEventPublisher applicationEventPublisher;
    @Autowired
    IDynamicGoodService dynamicGoodService;

    // 读取个人信息
    public UserInfoVo getUserInfo(LoginUser loginUser) {
        User user = userService.getById(loginUser.getUserId());
        if(user == null) {
            throw new ServiceException("用户不存在");
        }
        if(UserStatusEnum.forbidden.getValue() == user.getStatus()) {
            throw new ServiceException("当前用户已冻结，请联系客服");
        }
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setUserId(user.getId());
        userInfoVo.setAuthenticationType(user.getAuthenticationType());
        userInfoVo.setAuthenticationJobName(user.getAuthenticationJobName());
        userInfoVo.setAuthenticationClubName(user.getAuthenticationClubName());
        userInfoVo.setNickname(user.getUserNickName());
        if(StringUtils.isNotEmpty(user.getUserHeadPic())) {
            userInfoVo.setHeadPic(user.getUserHeadPic() + "?x-oss-process=image/resize,h_100,m_lfit");
        }
        userInfoVo.setPicList(user.getPicList());

        if (StringUtils.isNotEmpty(user.getPicList())) {
            String picList[] = user.getPicList().split(",");
            List<String> picConvertList = Arrays.stream(picList).map(item->{
                return item + "?x-oss-process=image/format,png";
            }).collect(Collectors.toList());
            userInfoVo.setPicListV2(StringUtils.join(picConvertList,"|"));
        }

        userInfoVo.setGender(user.getGender());
        userInfoVo.setSignature(user.getSignature());
        // 是否关注了公众号
        userInfoVo.setSubscribeMp(user.getSubscribeMp());
        if(user.getBirthday() != null) {
            userInfoVo.setBirthday(WzDateUtil.date2String(user.getBirthday(),WzDateUtil.DATE_FORMAT));
        }

        userInfoVo.setWechat(user.getWechat());
        // 加密一下手机号 涉及隐私 避免泄露
        userInfoVo.setPhone(PhoneUtil.hideBetween(user.getPhone()).toString());
        userInfoVo.setContactPhone(user.getContactPhone());
        userInfoVo.setUserOffice(user.getOfficeUser());
        // 添加统计字段
        statisticsUserInfoVo(userInfoVo);
        // 刷新 会员
        userVipResolver.resolve(userInfoVo,UserInfoVo::getUserId,((obj, vipOrNot) -> {
            userInfoVo.setVipOrNot(vipOrNot);
        }));

        return userInfoVo;
    }

    /***
     * 统计 用户维度数据
     * @param userInfoVo
     */
    public void statisticsUserInfoVo(UserInfoVo userInfoVo) {
        // 点赞数据
        Long goodCount = dynamicGoodService.count(
                new QueryWrapper<DynamicGood>()
                        .eq("author_user_id", userInfoVo.getUserId())
                        .eq("valid", true)
        );
        // 统计点赞数量
        userInfoVo.setGoodCount(goodCount.intValue());
        // 统计粉丝数量
        Long followCount = userAttentionService.count(new QueryWrapper<UserAttention>()
                .eq("attention_user_Id",userInfoVo.getUserId()).eq("valid", true)
        );
        userInfoVo.setFollowCount(followCount.intValue());
        // 统计关注数量
        Long attentionCount = userAttentionService.count(new QueryWrapper<UserAttention>()
                .eq("user_Id",userInfoVo.getUserId()).eq("valid", true)
        );
        userInfoVo.setAttentionCount(attentionCount.intValue());
    }

    /***
     * 用户头像昵称和性别必填
     * 时机1：创建活动的时候检查
     * 时机2：报名互动的时候检查
     * @param loginUser
     */
    public User userNeedInfoComplete(LoginUser loginUser) {
        User user = userService.getById(loginUser.getUserId());
        if(user == null) {
            throw new ServiceException("用户不存在");
        }
        if(user.getGender() == null) {
            throw new ServiceException("用户信息不完整，请补充后操作",HttpStatus.USER_IN_COMPLETE);
        }
        if(StringUtils.isEmpty(user.getUserHeadPic())) {
            throw new ServiceException("用户信息不完整，请补充后操作",HttpStatus.USER_IN_COMPLETE);
        }
        if(StringUtils.isEmpty(user.getUserNickName())) {
            throw new ServiceException("用户信息不完整，请补充后操作",HttpStatus.USER_IN_COMPLETE);
        }
        return user;
    }

    public void saveUpdateUserAuthentication(UserAuthenticationParam authenticationParam, LoginUser loginUser) {
        if(authenticationParam.getAuthenticationType() == null) {
            throw new ServiceException("认证类型不能为空");
        }
        if(UserAuthenticationTypeEnum.club.getValue() == authenticationParam.getAuthenticationType()) {
            if(authenticationParam.getClubLat() == null || authenticationParam.getClubLng() == null)
                throw new ServiceException("认证俱乐部地址必选");
            if(StringUtils.isEmpty(authenticationParam.getClubName()))
                throw new ServiceException("俱乐部名称必填");
            if(StringUtils.isEmpty(authenticationParam.getClubTel()))
                throw new ServiceException("俱乐部电话必填");
        }
        if(UserAuthenticationTypeEnum.person.getValue() == authenticationParam.getAuthenticationType()) {
            if(StringUtils.isEmpty(authenticationParam.getJobName()))
                throw new ServiceException("认证职业必填");
            if(StringUtils.isEmpty(authenticationParam.getPersonPicList()))
                throw new ServiceException("认证图片至少上传1张");
        }

        // 判断该用户是否存在
        UserAuthentication userAuthenticationSelect = userAuthenticationService.getOne(new QueryWrapper<UserAuthentication>().eq("user_id",loginUser.getUserId()),false);
        if(userAuthenticationSelect == null) {
            userAuthenticationSelect = new UserAuthentication();
            userAuthenticationSelect.setCreateDate(new Date());
            userAuthenticationSelect.setRemark("");
            userAuthenticationSelect.setUserId(loginUser.getUserId());
            userAuthenticationSelect.setStatus(AuditStatusEnum.auditing.getValue());
        }
        userAuthenticationSelect.setAuthenticationType(authenticationParam.getAuthenticationType());
        // 直接赋值
        if(UserAuthenticationTypeEnum.club.getValue() == authenticationParam.getAuthenticationType()) {
            userAuthenticationSelect.setClubLocation(GeoUtil.getWgs84Point(authenticationParam.getClubLat(),authenticationParam.getClubLng()));
            userAuthenticationSelect.setClubLat(authenticationParam.getClubLat());
            userAuthenticationSelect.setClubLng(authenticationParam.getClubLng());
            userAuthenticationSelect.setClubAddress(authenticationParam.getClubAddress());
            userAuthenticationSelect.setClubName(authenticationParam.getClubName());
            userAuthenticationSelect.setClubPic(authenticationParam.getClubPic());
            userAuthenticationSelect.setClubLocationName(authenticationParam.getClubLocationName());
            userAuthenticationSelect.setClubTel(authenticationParam.getClubTel());
        }else {
            userAuthenticationSelect.setJobName(authenticationParam.getJobName());
            userAuthenticationSelect.setPersonPicList(authenticationParam.getPersonPicList());
        }
        userAuthenticationSelect.setStatus(AuditStatusEnum.auditing.getValue());
        // 补充数据
        userAuthenticationService.saveOrUpdate(userAuthenticationSelect);
        // push
//        mpPushMessageService.pushMessageWxMpAdminMessageEvent(WxMpAdminMessageEvent.builder()
//                .pushTemplateEnum(PushTemplateEnum.AUTHTHENTICATION_COMMIT)
//                        .templateDataList(PushTemplateEnum.getAUTHTHENTICATION_COMMIT_Data(new Date(),
//                                UserAuthenticationTypeEnum.club.getValue() == authenticationParam.getAuthenticationType() ?
//                                        authenticationParam.getClubName() + authenticationParam.getClubTel() : authenticationParam.getJobName()))
//                .build());
    }

    public UserAuthenticationVo getUserAuthentication(LoginUser loginUser) {
        UserAuthentication userAuthentication = userAuthenticationService.getOne(
                new QueryWrapper<UserAuthentication>().eq("user_id",loginUser.getUserId())
        );
        UserAuthenticationVo userAuthenticationVo = new UserAuthenticationVo();
        if(userAuthentication == null) {
            return userAuthenticationVo;
        }
        BeanUtils.copyProperties(userAuthentication,userAuthenticationVo);

        if (StringUtils.isNotEmpty(userAuthentication.getPersonPicList())) {
            String picList[] = userAuthentication.getPersonPicList().split(",");
            List<String> picConvertList = Arrays.stream(picList).map(item->{
                return item + "?x-oss-process=image/format,png";
            }).collect(Collectors.toList());
            userAuthenticationVo.setPersonPicListV2(StringUtils.join(picConvertList,"|"));
        }

        return userAuthenticationVo;
    }

    public void updateUserInfo(UserInfoParam userInfoParam, LoginUser loginUser) {
        User user = userService.getById(loginUser.getUserId());
        if(user == null) {
            throw new ServiceException("用户不存在");
        }
        user.setPicList(userInfoParam.getPicList());
        // 如果第一张图片更换了需要更新头像
        if (StringUtils.isNotEmpty(user.getPicList())) {
            String picFirst = user.getPicList().split(",")[0];
            if(!picFirst.equals(user.getUserHeadPic())) {
                user.setUserHeadPic(picFirst);
            }
        }
        // 用户首次上传 保留通过头像更新的逻辑 其他情况均在个人中心信息里面统一维护图片
        if (StringUtils.isEmpty(user.getPicList()) && StringUtils.isNotEmpty(user.getUserHeadPic())) {
            user.setPicList(user.getUserHeadPic());
        }
        user.setUserNickName(userInfoParam.getNickname());
        user.setGender(userInfoParam.getGender());
        user.setSignature(userInfoParam.getSignature());
        if(StringUtils.isNotEmpty(userInfoParam.getBirthday())) {
            user.setBirthday(WzDateUtil.string2Date(userInfoParam.getBirthday(),WzDateUtil.DATE_FORMAT));
        }
        user.setWechat(userInfoParam.getWechat());
        user.setContactPhone(userInfoParam.getContactPhone());
        userService.updateById(user);
    }

    public UserInfoVo getUserInfoByUserId(Long userId, LoginUser loginUser) {
        User user = userService.getById(userId);
        if(user == null) {
            throw new ServiceException("用户不存在");
        }
        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setUserId(user.getId());
        userInfoVo.setAuthenticationType(user.getAuthenticationType());
        userInfoVo.setAuthenticationJobName(user.getAuthenticationJobName());
        userInfoVo.setAuthenticationClubName(user.getAuthenticationClubName());
        userInfoVo.setNickname(user.getUserNickName());
        userInfoVo.setHeadPic(user.getUserHeadPic() + "?x-oss-process=image/resize,h_100,m_lfit");
        userInfoVo.setPicList(user.getPicList());
        if (StringUtils.isNotEmpty(user.getPicList())) {
            String picList[] = user.getPicList().split(",");
            List<String> picConvertList = Arrays.stream(picList).map(item->{
                return item + "?x-oss-process=image/format,png";
            }).collect(Collectors.toList());
            userInfoVo.setPicListV2(StringUtils.join(picConvertList,"|"));
        }
        userInfoVo.setGender(user.getGender());
        userInfoVo.setSignature(user.getSignature());
        if(user.getBirthday() != null) {
            userInfoVo.setBirthday(WzDateUtil.date2String(user.getBirthday(),WzDateUtil.DATE_FORMAT));
        }
        statisticsUserInfoVo(userInfoVo);
        //
        // 刷新 会员
        userVipResolver.resolve(userInfoVo,UserInfoVo::getUserId,((obj, vipOrNot) -> {
            userInfoVo.setVipOrNot(vipOrNot);
        }));

        // 判断当前查询的用户和登录的用户绑定数据
        if (loginUser != null) {
            UserAttention userAttention = userAttentionService.getOne(
                    new QueryWrapper<UserAttention>()
                            .eq("user_id", loginUser.getUserId())
                            .eq("attention_user_id", userId)
                            .eq("valid", true)
            );
            if (userAttention != null) {
                userInfoVo.setUserAttentionOrNot(true);
            }
            UserDd userDd = userDdService.getOne(
                    new QueryWrapper<UserDd>()
                            .eq("send_user_id", loginUser.getUserId())
                            .eq("received_user_id", userId)
            );
            if (userDd != null) {
                userInfoVo.setDidiOrNot(true);
            }

        }

        return userInfoVo;
    }
    // 用户取消了公众号关注
    public void userUnSubscribeMp(String openId) {
        userService.update(
                new UpdateWrapper<User>()
                        .set("mp_openid", openId)
                        .set("subscribe_mp", false)
                        .eq("mp_openid", openId)
        );
    }
    // 用户关注了公众号关注
    public void userSubscribeMp(String unionId, String openId) {
        User user = userService.getOne(new QueryWrapper<User>().eq("unionId", unionId),false);
        // 如果用户没有任何信息 则直接新增一条
        if(user == null) {
            user = new User();
            user.setUnionid(unionId);
            user.setMpOpenid(openId);
            user.setSubscribeMp(true);
            user.setStatus(UserStatusEnum.normal.getValue());
            user.setCreateDate(new Date());
            user.setModifyDate(new Date());
            userService.save(user);
        }else {
            userService.update(
                    new UpdateWrapper<User>()
                            .set("mp_openid", openId)
                            .set("subscribe_mp", true)
                            .eq("unionId", unionId)
            );
        }
    }


    public Page<UserAttentionVo> getUserAttentionPage(Page page,Long userId,LoginUser loginUser) {
        Page<UserAttention> attentionPage = userAttentionService.page(page,
                new QueryWrapper<UserAttention>().eq("user_id",userId)
                        .eq("valid", true).orderByDesc("create_date")
        );
        if(CollectionUtils.isEmpty(attentionPage.getRecords())) {
            return page;
        }
        // 汇总
        List<Long> attentionUserIdList = attentionPage.getRecords().stream().map(UserAttention::getAttentionUserId).collect(Collectors.toList());
        // 查看我关注的用户有没有关注我  目的是处理 互相关注的状态
        List<UserAttention> userAttentionList = userAttentionService.list(
                new QueryWrapper<UserAttention>().in("user_id",attentionUserIdList)
                        .eq("attention_user_id", userId).eq("valid", true)
                        .orderByDesc("create_date")
        );
        List<UserAttentionVo> attentionVoList = new ArrayList<>();
        attentionPage.getRecords().forEach(item ->{
            UserAttentionVo attentionVo = new UserAttentionVo();
            attentionVo.setId(item.getId());
            attentionVo.setUserId(item.getAttentionUserId());
            // 状态 1：未关注 2：已关注 3：互相关注
            List<UserAttention> userAttentionList1 = userAttentionList.stream().filter(DO->DO.getUserId().compareTo(item.getAttentionUserId()) == 0).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(userAttentionList1)) {
                attentionVo.setStatus(3);
            } else {
                attentionVo.setStatus(2);
            }

            attentionVoList.add(attentionVo);
        });
        // 读取用户最新昵称和头像
        userInfoResolver.resolve(attentionVoList,UserAttentionVo::getUserId,((obj, nickName, headPic, gender,signature,phone,wechat) -> {
            obj.setNickname(nickName);
            obj.setHeadPic(headPic);
            obj.setSignature(signature);
            obj.setGender(gender);
        }));
        // 用户会员刷新
        userVipResolver.resolve(attentionVoList, UserAttentionVo::getUserId,((obj, vipOrNot)->{
            obj.setVipOrNot(vipOrNot);
        }));


        page.setRecords(attentionVoList);
        return page;
    }

    public Page<UserFollowVo> getUserFollowPage(Page page, Long userId,LoginUser loginUser) {

        Page<UserAttention> attentionPage = userAttentionService.page(page,
                new QueryWrapper<UserAttention>().eq("attention_user_id",userId)
                        .eq("valid", true).orderByDesc("create_date")
        );
        if(CollectionUtils.isEmpty(attentionPage.getRecords())) {
            return page;
        }
        // 汇总
        List<Long> userIdList = attentionPage.getRecords().stream().map(UserAttention::getUserId).collect(Collectors.toList());
        // 查看我关注的用户有没有关注我  目的是处理 互相关注的状态
        List<UserAttention> userAttentionList = userAttentionService.list(
                new QueryWrapper<UserAttention>().in("attention_user_id", userIdList)
                        .eq("user_id", userId).eq("valid", true)
                        .orderByDesc("create_date")
        );
        List<UserFollowVo> attentionVoList = new ArrayList<>();
        attentionPage.getRecords().forEach(item ->{
            UserFollowVo followVo = new UserFollowVo();
            followVo.setId(item.getId());
            followVo.setUserId(item.getUserId());
            // 状态 状态 1：粉丝 2：互相关注
            List<UserAttention> userAttentionList1 = userAttentionList.stream().filter(DO->DO.getAttentionUserId().compareTo(item.getUserId()) == 0).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(userAttentionList1)) {
                followVo.setStatus(2);
            } else {
                followVo.setStatus(1);
            }

            attentionVoList.add(followVo);
        });
        // 读取用户最新昵称和头像
        userInfoResolver.resolve(attentionVoList,UserFollowVo::getUserId,((obj, nickName, headPic, gender,signature,phone,wechat) -> {
            obj.setNickname(nickName);
            obj.setHeadPic(headPic);
            obj.setSignature(signature);
            obj.setGender(gender);
        }));
        userVipResolver.resolve(attentionVoList, UserFollowVo::getUserId,((obj, vipOrNot)->{
            obj.setVipOrNot(vipOrNot);
        }));
        page.setRecords(attentionVoList);
        return page;
    }

    public void commitUserAttention(Long userId, LoginUser loginUser) {
        //查询该用户是否关注过该人
        UserAttention userAttention = userAttentionService.getOne(new QueryWrapper<UserAttention>()
                .eq("user_id", loginUser.getUserId())
                .eq("attention_user_id", userId)
        );
        if(userAttention == null) {
            userAttention = new UserAttention();
            userAttention.setAttentionUserId(userId);
            userAttention.setUserId(loginUser.getUserId());
            userAttention.setCreateDate(new Date());
            userAttention.setValid(false);
            userAttentionService.save(userAttention);
        }
        userAttention.setValid(!userAttention.getValid());
        userAttentionService.updateById(userAttention);

        if(userAttention.getValid()) {
            // 发送消息
            applicationEventPublisher.publishEvent(UserMessageEvent.builder()
                    .userId(userAttention.getAttentionUserId())
                    .type(MessageTypeEnum.ATTENTION_MESSAGE)
                    .withContent("关注了你")
                    .withDynamicParam(loginUser.getUserId(), null ,"", loginUser.getUserId()).build());
        }
    }
}
